package cn.iocoder.yudao.module.worker.controller.app.reward;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import cn.iocoder.yudao.module.worker.controller.app.gift.vo.AppWorkerGiftRespVO;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerk.ClerkDO;
import cn.iocoder.yudao.module.worker.dal.dataobject.gift.WorkerGiftDO;
import cn.iocoder.yudao.module.worker.enums.reward.PlayStatusEnum;
import cn.iocoder.yudao.module.worker.service.clerk.ClerkService;
import cn.iocoder.yudao.module.worker.service.gift.WorkerGiftService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.annotation.security.PermitAll;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

import cn.iocoder.yudao.module.worker.controller.app.reward.vo.*;
import cn.iocoder.yudao.module.worker.dal.dataobject.reward.WorkerRewardDO;
import cn.iocoder.yudao.module.worker.service.reward.WorkerRewardService;

@Tag(name = "用户 APP - 打赏记录")
@RestController
@RequestMapping("/worker/reward")
@Validated
public class AppWorkerRewardController {

    @Resource
    private WorkerRewardService rewardService;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private WorkerGiftService workerGiftService;

    @Resource
    private ClerkService clerkService;

    @PostMapping("/create")
    @Operation(summary = "创建打赏记录")
    public CommonResult<Long> createReward(@Valid @RequestBody AppWorkerRewardSaveReqVO createReqVO) {
        return success(rewardService.createReward(createReqVO));
    }

    @PostMapping("/createOrder")
    @Operation(summary = "创建打赏订单")
    @PreAuthenticated
    public CommonResult<AppWorkerRewardRespVO> createOrder(@Valid @RequestBody AppWorkerRewardSaveReqVO createReqVO) {
        return success(rewardService.createOrder(getLoginUserId(), createReqVO));
    }

    @PostMapping("/update-paid")
    @Operation(summary = "更新打赏为已支付") // 由 pay-module 支付服务，进行回调，可见 PayNotifyJob
    @PermitAll // 无需登录， 内部校验实现
    public CommonResult<Boolean> updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
        rewardService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
                notifyReqDTO.getPayOrderId());
        return success(true);
    }

    @PutMapping("/update")
    @Operation(summary = "更新打赏记录")
    public CommonResult<Boolean> updateReward(@Valid @RequestBody AppWorkerRewardSaveReqVO updateReqVO) {
        rewardService.updateReward(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除打赏记录")
    @Parameter(name = "id", description = "编号", required = true)
    public CommonResult<Boolean> deleteReward(@RequestParam("id") Long id) {
        rewardService.deleteReward(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得打赏记录")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<AppWorkerRewardRespVO> getReward(@RequestParam("id") Long id) {
        WorkerRewardDO reward = rewardService.getReward(id);
        return success(BeanUtils.toBean(reward, AppWorkerRewardRespVO.class));
    }

    @GetMapping("/getTopList")
    @Operation(summary = "获得最近打赏列表")
    public CommonResult<List<AppWorkerGiftRespVO>> getTopList() {
        List<WorkerRewardDO> list = rewardService.getTopList();
        if (CollUtil.isEmpty(list)) {
            return success(CollectionUtils.newArrayList(new ArrayList<>()));
        }

        List<MemberUserRespDTO> userList = memberUserApi.getUserList(convertSet(list, WorkerRewardDO::getUserId));
        Map<Long, MemberUserRespDTO> userMap = convertMap(userList, MemberUserRespDTO::getId);

        List<WorkerGiftDO> giftList = workerGiftService.getGiftList(convertSet(list, WorkerRewardDO::getGiftId));
        Map<Long, WorkerGiftDO> mapGift = convertMap(giftList, WorkerGiftDO::getId);

        List<ClerkDO> clerkList = clerkService.getClerkList(convertSet(list, WorkerRewardDO::getWorkerClerkId));
        Map<Long, ClerkDO> clerkMap = convertMap(clerkList, ClerkDO::getId);

        List<MemberUserRespDTO> workerUserList = memberUserApi.getUserList(convertSet(list, WorkerRewardDO::getWorkerUserId));
        Map<Long, MemberUserRespDTO> workerUserMap = convertMap(workerUserList, MemberUserRespDTO::getId);

        List<AppWorkerGiftRespVO> pageList = BeanUtils.toBean(list, AppWorkerGiftRespVO.class);
        for(AppWorkerGiftRespVO page : pageList){
            page.setUsername(userMap.getOrDefault(page.getUserId(), new MemberUserRespDTO()).getNickname());
            page.setName(mapGift.getOrDefault(page.getGiftId(), new WorkerGiftDO()).getName());
            page.setGiftType(mapGift.getOrDefault(page.getGiftId(), new WorkerGiftDO()).getGiftType());
            page.setPic(mapGift.getOrDefault(page.getGiftId(), new WorkerGiftDO()).getPic());
            if(page.getWorkerClerkId() != null){
                page.setNickname(clerkMap.getOrDefault(page.getWorkerClerkId(), new ClerkDO()).getNickname());
            }else{
                page.setNickname(workerUserMap.getOrDefault(page.getWorkerUserId(), new MemberUserRespDTO()).getNickname());
            }
        }


        return success(pageList);
    }

    @GetMapping("/getGiftList")
    @Operation(summary = "获得打赏列表")
    public CommonResult<List<AppWorkerGiftRespVO>> getGiftList(@Valid AppWorkerRewardPageReqVO pageReqVO) {
        // 查询所有的礼物
        List<WorkerGiftDO> giftList = workerGiftService.getAllGiftList();
        if (CollUtil.isEmpty(giftList)) {
            return success(CollectionUtils.newArrayList(new ArrayList<>()));
        }

        List<AppWorkerGiftRespVO> giftRespList = new ArrayList<>();

        // 查询打赏店员的礼物
        List<WorkerRewardDO> rewardList = rewardService.getGiftList(pageReqVO.getWorkerUserId(), pageReqVO.getWorkerClerkId());
        Map<Long, List<WorkerRewardDO>> mapReward = convertMultiMap(rewardList, WorkerRewardDO::getGiftId);

        for(WorkerGiftDO giftDO : giftList){
            AppWorkerGiftRespVO giftResp = BeanUtils.toBean(giftDO, AppWorkerGiftRespVO.class);

            List<WorkerRewardDO> rewardDOList = mapReward.get(giftDO.getId());
            if(giftDO.getStatus()){
                if(CollectionUtils.isAnyEmpty(rewardDOList)){
                    giftResp.setPlayNum(0);
                    giftResp.setPlayStatus(PlayStatusEnum.UN_STAR.getPlayStatus());
                }else{
                    Integer playNum = CollectionUtils.getSumValue(rewardDOList, WorkerRewardDO::getCount, Integer::sum);
                    giftResp.setPlayNum(playNum);
                    giftResp.setPlayStatus(PlayStatusEnum.STAR.getPlayStatus());
                }
                giftRespList.add(giftResp);
            }else{
                if(!CollectionUtils.isAnyEmpty(rewardDOList)){
                    Integer playNum = CollectionUtils.getSumValue(rewardDOList, WorkerRewardDO::getCount, Integer::sum);
                    giftResp.setPlayNum(playNum);
                    giftResp.setPlayStatus(PlayStatusEnum.UN_VISIBLE.getPlayStatus());
                    giftRespList.add(giftResp);
                }
            }
        }
        return success(giftRespList);
    }

    @GetMapping("/page")
    @Operation(summary = "获得打赏记录分页")
    @PreAuthenticated
    public CommonResult<PageResult<AppWorkerRewardRespVO>> getRewardPage(@Valid AppWorkerRewardPageReqVO pageReqVO) {
        pageReqVO.setWorkerUserId(getLoginUserId());
        PageResult<WorkerRewardDO> pageResult = rewardService.getRewardPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }
        // 查询用户集合
        List<MemberUserRespDTO> userList = memberUserApi.getUserList(convertSet(pageResult.getList(), WorkerRewardDO::getUserId));
        Map<Long, MemberUserRespDTO> mapUser = convertMap(userList, MemberUserRespDTO::getId);

        return success(BeanUtils.toBean(pageResult, AppWorkerRewardRespVO.class,
                conversation ->
                        conversation.setAvatar(mapUser.getOrDefault(conversation.getUserId(), new MemberUserRespDTO()).getAvatar())
                                .setNickname(mapUser.getOrDefault(conversation.getUserId(), new MemberUserRespDTO()).getNickname())));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出打赏记录 Excel")
    @ApiAccessLog(operateType = EXPORT)
    public void exportRewardExcel(@Valid AppWorkerRewardPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<WorkerRewardDO> list = rewardService.getRewardPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "打赏记录.xls", "数据", AppWorkerRewardRespVO.class,
                        BeanUtils.toBean(list, AppWorkerRewardRespVO.class));
    }

}